const fs = require('fs');
const path = require('path');

/**
 * 数据验证工具类
 * 用于剔除无效数据（key和内部name字段不匹配的数据）
 */
class DataValidator {
    constructor() {
        this.validData = [];
        this.invalidData = [];
        this.stats = {
            total: 0,
            valid: 0,
            invalid: 0
        };
    }

    /**
     * 验证单个数据项
     * @param {string} key - 数据的key
     * @param {Object} data - 数据对象
     * @returns {boolean} - 是否有效
     */
    validateItem(key, data) {
        // 检查数据对象是否存在且包含name字段
        if (!data || typeof data !== 'object' || !data.name) {
            return false;
        }

        // 检查key和name是否匹配
        return key === data.name;
    }

    /**
     * 验证整个数据集
     * @param {Object} dataSet - 要验证的数据集
     * @returns {Object} - 验证结果统计
     */
    validateDataSet(dataSet) {
        this.validData = [];
        this.invalidData = [];
        this.stats = {
            total: 0,
            valid: 0,
            invalid: 0
        };

        if (!dataSet || typeof dataSet !== 'object') {
            throw new Error('无效的数据集格式');
        }

        // 遍历数据集
        for (const [key, value] of Object.entries(dataSet)) {
            this.stats.total++;

            if (this.validateItem(key, value)) {
                // 有效数据：将key作为location字段，保留所有其他字段
                const validItem = {
                    location: key,
                    ...value
                };
                this.validData.push(validItem);
                this.stats.valid++;
            } else {
                // 无效数据：记录key和name不匹配的情况
                const invalidItem = {
                    key: key,
                    expectedName: key,
                    actualName: value?.name || 'undefined',
                    data: value
                };
                this.invalidData.push(invalidItem);
                this.stats.invalid++;
            }
        }

        return this.stats;
    }

    /**
     * 获取有效数据数组
     * @returns {Array} - 有效数据数组
     */
    getValidData() {
        return this.validData;
    }

    /**
     * 获取无效数据数组
     * @returns {Array} - 无效数据数组
     */
    getInvalidData() {
        return this.invalidData;
    }

    /**
     * 获取验证统计信息
     * @returns {Object} - 统计信息
     */
    getStats() {
        return this.stats;
    }

    /**
     * 保存数据到文件
     * @param {string} filePath - 文件路径
     * @param {Array} data - 要保存的数据
     * @param {string} format - 文件格式 ('json' 或 'csv')
     */
    saveToFile(filePath, data, format = 'json') {
        try {
            const dir = path.dirname(filePath);
            if (!fs.existsSync(dir)) {
                fs.mkdirSync(dir, { recursive: true });
            }

            if (format === 'json') {
                fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf8');
            } else if (format === 'csv') {
                const csvContent = this.convertToCSV(data);
                fs.writeFileSync(filePath, csvContent, 'utf8');
            } else {
                throw new Error('不支持的文件格式');
            }

            console.log(`数据已保存到: ${filePath}`);
        } catch (error) {
            console.error('保存文件时出错:', error.message);
            throw error;
        }
    }

    /**
     * 将数据转换为CSV格式
     * @param {Array} data - 数据数组
     * @returns {string} - CSV字符串
     */
    convertToCSV(data) {
        if (!data || data.length === 0) {
            return '';
        }

        // 获取所有可能的字段
        const allFields = new Set();
        data.forEach(item => {
            Object.keys(item).forEach(key => allFields.add(key));
        });

        const fields = Array.from(allFields);

        // 创建CSV头部
        const header = fields.join(',');

        // 创建CSV行
        const rows = data.map(item => {
            return fields.map(field => {
                const value = item[field];
                // 如果值包含逗号或引号，用引号包围并转义内部引号
                if (typeof value === 'string' && (value.includes(',') || value.includes('"'))) {
                    return `"${value.replace(/"/g, '""')}"`;
                }
                return value || '';
            }).join(',');
        });

        return [header, ...rows].join('\n');
    }

    /**
     * 生成详细的验证报告
     * @param {string} outputDir - 输出目录
     */
    generateReport(outputDir = './output') {
        const timestamp = new Date().toISOString().replace(/[:.]/g, '-');

        // 保存有效数据
        const validDataPath = path.join(outputDir, `valid_data_${timestamp}.json`);
        this.saveToFile(validDataPath, this.validData, 'json');

        // 保存无效数据（用于调试）
        const invalidDataPath = path.join(outputDir, `invalid_data_${timestamp}.json`);
        this.saveToFile(invalidDataPath, this.invalidData, 'json');

        // 保存CSV格式的有效数据
        const csvPath = path.join(outputDir, `valid_data_${timestamp}.csv`);
        this.saveToFile(csvPath, this.validData, 'csv');

        // 生成统计报告
        const reportPath = path.join(outputDir, `validation_report_${timestamp}.txt`);
        const report = this.generateReportText();
        fs.writeFileSync(reportPath, report, 'utf8');

        console.log(`验证报告已生成: ${reportPath}`);
    }

    /**
     * 生成文本格式的验证报告
     * @returns {string} - 报告文本
     */
    generateReportText() {
        const stats = this.getStats();
        const report = [
            '数据验证报告',
            '='.repeat(50),
            `生成时间: ${new Date().toLocaleString('zh-CN')}`,
            '',
            '统计信息:',
            `  总数据量: ${stats.total}`,
            `  有效数据: ${stats.valid}`,
            `  无效数据: ${stats.invalid}`,
            `  有效率: ${((stats.valid / stats.total) * 100).toFixed(2)}%`,
            '',
            '数据格式说明:',
            '  有效数据格式: [{"location": "地点名称", "act_id": 100, "area_id": 43, ...}]',
            '  无效数据格式: [{"key": "原始key", "expectedName": "期望名称", "actualName": "实际名称", "data": {...}}]',
            '',
            '注意事项:',
            '  1. 有效数据中的location字段来自原始数据的key',
            '  2. 无效数据通常是因为key和内部name字段不匹配',
            '  3. 建议检查无效数据，确认数据源的正确性'
        ].join('\n');

        return report;
    }
}

module.exports = DataValidator;
